package org.jsola.hr.task;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.jsola.hr.dao.IAttendPeopleMonthlyStatDAO;
import org.jsola.hr.dao.IAttendPlanDAO;
import org.jsola.hr.entity.*;
import org.jsola.hr.query.AttendPunchDeptQuery;
import org.jsola.hr.query.AttendPunchStaffQuery;
import org.jsola.hr.query.EmpDepQuery;
import org.jsola.hr.service.*;
import org.jsola.hr.vo.StaffVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 打卡人员月统计
 *
 * h_attend_people_monthly_stat
 *
 * @author wxz
 */
@Component
public class AttendPeopleMonthlyTask {

    @Autowired
    private IAttendPeopleMonthlyStatDAO attendPeopleMonthlyStatDAO;
    @Autowired
    private IAttendPlanDAO attendPlanDAO;
    @Autowired
    private IEmpDepService empDepService;
    @Autowired
    private IEmpInfoService empInfoService;
    @Autowired
    private IAttendPunchStaffService attendPunchStaffService;
    @Autowired
    private IAttendPunchDeptService attendPunchDeptService;
    @Autowired
    private IDepInfoService depInfoService;
    @Autowired
    private IAttendPeopleMonthlyStatService attendPeopleMonthlyStatService;

    @Scheduled(cron = "0 0 1 1 * ?") // 每月1号凌晨1点执行一次
    public void monthlyStat() {

        String yearly = DateFormatUtils.format(new Date(), "yyyy");
        String monthly = DateFormatUtils.format(new Date(), "MM");

        // 查询所有的考勤规则
        Example example = new Example(AttendPlanDO.class);
        example.and()
                .andEqualTo("valid", true);
        List<AttendPlanDO> attendPlanList = attendPlanDAO.selectByExample(example);
        if (attendPlanList.size() <= 0) {
            return;
        }

        // 考勤打卡参与人员
        for (AttendPlanDO plan : attendPlanList) {

            Set<StaffVO> staffIds = new HashSet<StaffVO>();

            // 查询考勤打卡参与人员
            Set<StaffVO> set1 = this.getStaffSetForPunchStaff(plan.getId(), plan.getSiteId());
            if (set1.size() > 0) {
                for (StaffVO staffVO : set1) {
                    staffIds.add(staffVO);
                }
            }

            // 查询考勤打卡参与部门
            Set<StaffVO> set2 = this.getStaffSetForPunchDep(plan.getId(), plan.getSiteId());
            if (set2.size() > 0) {
                for (StaffVO staffVO : set2) {
                    staffIds.add(staffVO);
                }
            }

            if (staffIds.size() > 0) {

                for (StaffVO staff : staffIds) {

                    // 查询员工所在部门
                    DepInfoDO depInfo = getDepInfo(staff.getEmpInfoId(), plan.getSiteId());

                    AttendPeopleMonthlyStatDO monthlyStat = new AttendPeopleMonthlyStatDO();

                    monthlyStat.setAttendPlanId(plan.getId());
                    // 公司ID
                    monthlyStat.setCompanyId(plan.getCompanyId());
                    // 公司名称
                    monthlyStat.setCompanyName(plan.getCompanyName());
                    // 部门ID
                    monthlyStat.setDeptId(depInfo != null ? depInfo.getId() : "");
                    // 部门名称
                    monthlyStat.setDeptName(depInfo != null ? depInfo.getName() : "");
                    // 员工ID
                    monthlyStat.setEmpInfoId(staff.getEmpInfoId());
                    // 员工姓名
                    monthlyStat.setEmpInfoName(staff.getEmpInfoName());
                    // 工号
                    monthlyStat.setJobNumber("");
                    // 年
                    monthlyStat.setYearly(yearly);
                    // 月
                    monthlyStat.setMonthly(monthly);
                    // 应出勤天数
                    int shouldWorkDays = attendPeopleMonthlyStatService.calShoutWorkDays(plan.getId(), yearly, monthly, plan.getSiteId());
                    monthlyStat.setShouldWorkDays(shouldWorkDays);
                    // 出勤天数
                    monthlyStat.setAttendDays(0);
                    // 休息天数
                    monthlyStat.setRestDays(0);
                    // 迟到次数
                    monthlyStat.setLateCounts(0);
                    // 上班缺卡次数
                    monthlyStat.setOnWorkMissCounts(0);
                    // 下班缺卡次数
                    monthlyStat.setOffWorkMissCounts(0);
                    // 旷工天数
                    monthlyStat.setAbsenteeismDays(new BigDecimal("0"));
                    // 请假天数
                    monthlyStat.setLeaveDays(new BigDecimal("0"));
                    monthlyStat.setCreateUserId("");
                    monthlyStat.setGmtCreate(new Date());
                    monthlyStat.setModifiedUserId("");
                    monthlyStat.setGmtModified(new Date());
                    monthlyStat.setSiteId(plan.getSiteId());
                    monthlyStat.setValid(true);

                    attendPeopleMonthlyStatDAO.insert(monthlyStat);
                }
            }
        }  // 结束规则循环
    }

    /**
     *
     * @param empInfoId
     * @param siteId
     * @return
     */
    private DepInfoDO getDepInfo(String empInfoId, String siteId) {

        DepInfoDO depInfoDO = null;

        EmpDepQuery empDepQuery = new EmpDepQuery();
        empDepQuery.setEmpId(empInfoId);
        List<EmpDepDO> empDepList = empDepService.selectDO(empDepQuery, siteId);
        if (empDepList.size() <= 0) {
            return depInfoDO;
        }

        // 查询部门信息
        depInfoDO = depInfoService.selectDOById(empDepList.get(0).getDepId(), siteId);

        return depInfoDO;
    }

    /**
     * 从打卡人员当中获取打卡人员
     *
     * @param attendPlanId
     * @param siteId
     */
    private Set<StaffVO> getStaffSetForPunchStaff(String attendPlanId, String siteId) {

        Set<StaffVO> staffIds = new HashSet<StaffVO>();

        // 查询考勤打卡参与人员
        AttendPunchStaffQuery attendPunchStaffQuery = new AttendPunchStaffQuery();
        attendPunchStaffQuery.setAttendPlanId(attendPlanId);
        List<AttendPunchStaffDO> staffList = attendPunchStaffService.selectDO(attendPunchStaffQuery, siteId);
        if (staffList != null && staffList.size() > 0) {
            for (AttendPunchStaffDO attendPunchStaff : staffList) {

                StaffVO staffVO = new StaffVO();
                staffVO.setEmpInfoId(attendPunchStaff.getEmpInfoId());
                staffVO.setEmpInfoName(attendPunchStaff.getEmpInfoName());
                staffIds.add(staffVO);
            }
        }

        return staffIds;
    }

    /**
     * 从考勤部门当中获取打卡人员
     *
     * @param attendPlanId
     * @param siteId
     * @return
     */
    private Set<StaffVO> getStaffSetForPunchDep(String attendPlanId, String siteId) {

        Set<StaffVO> staffIds = new HashSet<StaffVO>();

        // 查询考勤打卡参与部门
        AttendPunchDeptQuery attendPunchDeptQuery = new AttendPunchDeptQuery();
        attendPunchDeptQuery.setAttendPlanId(attendPlanId);
        List<AttendPunchDeptDO> deptList = attendPunchDeptService.selectDO(attendPunchDeptQuery, siteId);
        if (deptList != null && deptList.size() > 0) {
            for (AttendPunchDeptDO dept : deptList) {

                // 查询部门下的人员
                EmpDepQuery empDepQuery = new EmpDepQuery();
                empDepQuery.setDepId(dept.getDeptId());
                List<EmpDepDO> empDepList = empDepService.selectDO(empDepQuery, dept.getSiteId());
                if (empDepList.size() > 0) {
                    for (EmpDepDO empDep : empDepList) {

                        // 查询人员信息
                        EmpInfoDO empInfoDO = empInfoService.selectDOById(empDep.getEmpId(), empDep.getSiteId());
                        if (empInfoDO != null) {
                            StaffVO staffVO = new StaffVO();
                            staffVO.setEmpInfoId(empInfoDO.getId());
                            staffVO.setEmpInfoName(empInfoDO.getName());
                            staffIds.add(staffVO);
                        }
                    }
                }
            }
        }

        return staffIds;
    }


}
